package com.black.utils.math;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class VerticalCalculatePrinter {

    public static final String SPACE = " ";
    public static final char ZERO = '0';
    public static final char DOT = '.';
    public static final String LINE = "─";

    public static void divide(double a, double b, int scale) {
        if (b==0) {
            System.out.println("除数不能为0");
            return;
        }

        System.out.println(a + " ÷ " + b);

        int shift = Math.max(getDecimalPlaces(a), getDecimalPlaces(b));
        BigDecimal A = BigDecimal.valueOf(a).movePointRight(shift);
        BigDecimal B = BigDecimal.valueOf(b).movePointRight(shift);

        long dividend = A.longValue();
        long divisor = B.longValue();

        if (shift > 0) {
            System.out.println("等效除法: " + dividend + " ÷ " + divisor);
        }

        printDivision(dividend, divisor, scale);
    }

    private static void printDivision(long dividend, long divisor, int scale) {
        String dividendStr = String.valueOf(dividend);
        String result = getResult(divisor, scale, dividend);
        int topLineLen = dividendStr.length() + 2;
        String topLine = repeatStr(LINE, topLineLen);

        // 打印顶部
        int i = 1;
        int temp = Integer.parseInt(String.valueOf(dividend).substring(0, i));
        while (temp < divisor) {
            temp = Integer.parseInt(String.valueOf(dividend).substring(0, ++i));
        }
        System.out.println(spaces(divisor) + repeatStr(SPACE, i) + result);
        System.out.println(spaces(divisor) + "┌" + topLine);
        System.out.println(divStr(divisor) + " |" + dividendStr);

        // 打印逐步计算
        printSteps(divisor, dividendStr, scale);
        System.out.println("\n结果 = " + result);
    }

    private static String getResult(long divisor, int scale, long dividendStr) {
        BigDecimal result = BigDecimal.valueOf(dividendStr).divide(BigDecimal.valueOf(divisor), scale, RoundingMode.DOWN);
        return result.toPlainString();
    }

    private static void printSteps(long divisor, String dividendStr, int scale) {
        long remainder = 0;
        int currentPos = String.valueOf(divisor).length() + 2; // 当前打印列位置

        for (int i = 0; i < dividendStr.length(); i++) {
            int digit = dividendStr.charAt(i) - ZERO;
            remainder = remainder * 10 + digit;

            if (remainder >= divisor) {
                long q = remainder / divisor;
                long sub = q * divisor;
                long newRem = remainder - sub;

                // 计算当前对齐偏移
                String pad = repeatStr(SPACE, currentPos);

                System.out.println(pad + sub);
                System.out.println(pad + repeatStr(LINE, String.valueOf(sub).length() + 2));
                if (i < dividendStr.length() - 1) {
                    System.out.println(pad + SPACE + newRem + dividendStr.charAt(i + 1));
                } else {
                    System.out.println(pad + SPACE + newRem + ZERO);
                }

                // 下一轮偏移 = 当前偏移 + 本轮(sub)长度 - 余数长度
                currentPos += String.valueOf(sub).length() - String.valueOf(newRem).length();
                remainder = newRem;
            }
        }

        // 小数部分
        if (remainder!=0) {
            for (int i = 0; i < scale && remainder!=0; i++) {
                remainder *= 10;
                int tempLen = String.valueOf(remainder).length();
                long q = remainder / divisor;
                long sub = q * divisor;
                remainder -= sub;

                String pad = repeatStr(SPACE, currentPos);
                if (String.valueOf(sub).length() < tempLen) {
                    currentPos += 1;
                    System.out.println(pad + SPACE + sub);
                } else {
                    System.out.println(pad + sub);
                }
                System.out.println(pad + repeatStr(LINE, String.valueOf(sub).length() + 2));
                System.out.println(pad + SPACE + remainder + ZERO);

                currentPos += String.valueOf(sub).length() - String.valueOf(remainder).length();
            }
        }
    }


    private static String repeatStr(String s, int count) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < count; i++) sb.append(s);
        return sb.toString();
    }

    private static String spaces(long divisor) {
        return repeatStr(SPACE, String.valueOf(divisor).length() + 1);
    }

    private static String divStr(long divisor) {
        return String.valueOf(divisor);
    }

    private static int getDecimalPlaces(double num) {
        String s = String.valueOf(num);
        int idx = s.indexOf(DOT);
        return idx==-1 ? 0:s.length() - idx - 1;
    }
}
